﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using DataLibs;
using URLsGetter;
using httpGetter;
using CommonLib;
using filesIO;

namespace LinksMining {
    public class LinksMining
    {
        const string DefaultOutputFileName = "out.txt";
        private static int _maxParallelThreadCount = 2;

        private string _inputFile;
        private string _outputFile;

        static object writeLockObj = new object();
        static int threadCount = 0;

        static public int MaxParallelThreadCount {
            get { return _maxParallelThreadCount; }
            set { _maxParallelThreadCount = value; }
        }

        
        public LinksMining(string inputFile) {
            _inputFile = inputFile;
            _outputFile = DefaultOutputFileName;

            try {
                Start();
            } catch (Exception e) {
                // TODO: Needs implementation
            }
        }

        public LinksMining(string inputFile, string outputFile) {
            _inputFile = inputFile;
            
            try
            {
                Start();
            } catch (Exception e) {
                // TODO: Needs implementation
            }

        }

        void Start() {
            URLsGetter.URLsGetter urlsGetter = new URLsGetter.URLsGetter(_inputFile);

            Thread[] urlThread = new Thread[urlsGetter.URLs.Count()];
            
            //for (int ParallelThreadCount = 0; ParallelThreadCount < _maxParallelThreadCount; ParallelThreadCount++) {
            //}

            for (int urlCount = 0; urlCount < urlsGetter.URLs.Count(); urlCount++) {
                urlThread[urlCount] = new Thread(new ParameterizedThreadStart(processingURL));
                urlThread[urlCount].Name = urlsGetter.URLs[urlCount];
                urlThread[urlCount].Start((object)urlsGetter.URLs[urlCount]);

                // processingURL(urlsGetter.URLs[urlCount]);
            }

            do {
                Thread.Sleep(1000);
            } while (threadCount != 0);

        }

        void processingURL(object UrlObj) {
            
            string url = (string)UrlObj;

            Monitor.Enter(writeLockObj);

            try {
                threadCount++;
            } finally {
                Monitor.Exit(writeLockObj);
            }
            Console.WriteLine((string)Thread.CurrentThread.Name);
            httpGetter.httpGetter getHtmlData = new httpGetter.httpGetter(url);
            
            htmlData htmlData;

            try {
                htmlData = getHtmlData.getDataViaHTTP();
            } catch {
                //Console.WriteLine("ERROR: Cannot capture html form {0}", url);
                return;
            }

            htmlParser.htmlParser parsedDATA = new htmlParser.htmlParser(htmlData);

            parsedDATA.LocalDomain = url;

            List<ParseResult> DataList = parsedDATA.parsing();

            saveResult(htmlData, DataList);
        }


        void saveResult(htmlData hd, List<ParseResult> DataList) {
            
            string url2file = string.Empty;
            
            for (int i = 0; i < hd.URL.Length; i++) {
                url2file += Char2Hex.Convert(hd.URL[i]);
            }
            Monitor.Enter(writeLockObj);

            try {
                FileWrite.WriteFile(_outputFile, string.Format("{0} {1}", url2file, hd.Time));

                foreach (ParseResult pr in DataList) {
                    FileWrite.WriteFile(_outputFile, pr.ToString());
                }
                threadCount--;
            } finally {
                Monitor.Exit(writeLockObj);
            }
            
        }
    }
}
